package com.rxweather.domain.usercase;
import android.content.res.AssetManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.HandlerThread;
import android.support.annotation.NonNull;
import android.util.SparseArray;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.jakewharton.rxbinding.internal.MainThreadSubscription;
import com.joker.rxweather.common.Constants;
import com.joker.rxweather.common.rx.rxAndroid.SchedulersCompat;
import com.joker.rxweather.model.entities.AddressEntity;
import com.joker.rxweather.model.entities.RequestCitiesEntity;
import com.joker.rxweather.model.request.PrepareRequest;
import com.joker.rxweather.model.service.ServiceRest;
import com.rxweather.domain.LocationListenerAdapter;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.json.JSONObject;
import rx.Observable;
import rx.Subscriber;
import rx.functions.Func1;
import rx.functions.Func2;
/**
* Created by Joker on 2015/10/31.
*/
public class PrepareCase extends UseCase<SparseArray, PrepareRequest> {
private static final String TAG = PrepareCase.class.getSimpleName();
private HandlerThread handlerThread;
private RequestCitiesEntity requestCitiesEntity = null;
public PrepareCase() {
}
@Override protected Observable<SparseArray> interactor(PrepareRequest prepareRequest) {
this.handlerThread = new HandlerThread("backgroundThread");
this.handlerThread.start();
return Observable.zip(PrepareCase.this.getLocationObservable(prepareRequest.locationManager),
PrepareCase.this.getRequestCitiesObservable(prepareRequest.assetManager),
new Func2<AddressEntity, List<RequestCitiesEntity.RequestCity>, SparseArray>() {
@Override public SparseArray call(AddressEntity locationEntity,
List<RequestCitiesEntity.RequestCity> requestCities) {
SparseArray sparseArray = new SparseArray(2);
sparseArray.put(Constants.LOCATION_TAG, locationEntity);
sparseArray.put(Constants.FORECAST_TAG, requestCities);
return sparseArray;
}
});
}
@NonNull
private Observable<AddressEntity> getLocationObservable(final LocationManager locationManager) {
return Observable.create(new Observable.OnSubscribe<Location>() {
@Override public void call(final Subscriber<? super Location> subscriber) {
final LocationListener locationListener = new LocationListenerAdapter() {
public void onLocationChanged(final Location location) {
if (!subscriber.isUnsubscribed()) {
subscriber.onNext(location);
subscriber.onCompleted();
}
locationManager.removeUpdates(this);
handlerThread.getLooper().quit();
}
};
subscriber.add(new MainThreadSubscription() {
@Override protected void onUnsubscribe() {
locationManager.removeUpdates(locationListener);
handlerThread.getLooper().quit();
}
});
final Criteria locationCriteria = new Criteria();
locationCriteria.setAccuracy(Criteria.ACCURACY_COARSE);
locationCriteria.setPowerRequirement(Criteria.POWER_LOW);
final String locationProvider = locationManager.getBestProvider(locationCriteria, true);
locationManager.requestSingleUpdate(locationProvider, locationListener,
handlerThread.getLooper());
}
}).concatMap(new Func1<Location, Observable<AddressEntity>>() {
@Override public Observable<AddressEntity> call(Location location) {
return ServiceRest.getInstance().getCityByCoordinate(location);
}
});
}
private Observable<List<RequestCitiesEntity.RequestCity>> getRequestCitiesObservable(
final AssetManager assetManager) {
return Observable.create(new Observable.OnSubscribe<List<RequestCitiesEntity.RequestCity>>() {
@Override
public void call(final Subscriber<? super List<RequestCitiesEntity.RequestCity>> subscriber) {
if (!subscriber.isUnsubscribed()) {
if (requestCitiesEntity == null) {
InputStream in = null;
try {
in = assetManager.open("city.txt");
byte[] arrayOfByte = new byte[in.available()];
in.read(arrayOfByte);
JSONObject jsonObject = new JSONObject(new String(arrayOfByte, "UTF-8"));
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
.serializeNulls()
.create();
requestCitiesEntity = gson.fromJson(jsonObject.toString(), RequestCitiesEntity.class);
} catch (Exception e) {
subscriber.onError(e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
subscriber.onError(e);
}
}
}
}
subscriber.onNext(requestCitiesEntity.getRequestCityList());
subscriber.onCompleted();
}
}
}).compose(SchedulersCompat.<List<RequestCitiesEntity.RequestCity>>applyIoSchedulers());
}
}